package com.sxhuayuan.parking.plugin.parking.che_an;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sxhuayuan.parking.compenent.Message;
import com.sxhuayuan.parking.compenent.web.RespMessage;
import com.sxhuayuan.parking.config.Platform;
import com.sxhuayuan.parking.dto.CreateMcardChargeOrderDTO;
import com.sxhuayuan.parking.dto.ParkFeeCacheBean;
import com.sxhuayuan.parking.entity.Member;
import com.sxhuayuan.parking.entity.MemberCarPlate;
import com.sxhuayuan.parking.entity.Order;
import com.sxhuayuan.parking.entity.ParkChannel;
import com.sxhuayuan.parking.entity.ParkingIn;
import com.sxhuayuan.parking.entity.ParkingLot;
import com.sxhuayuan.parking.exception.MyException;
import com.sxhuayuan.parking.plugin.parking.ParkingPlugin;
import com.sxhuayuan.parking.plugin.parking.bean.McardChargeOption;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnBaseData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnMcardAddRequestData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnMcardCancelRequestData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnMcardChargeOrderCreateRequestData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnMcardNotifyChargeSuccessRequestData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnMcardQueryRequestData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnQueryLeavingCarParkingFeeRequestData;
import com.sxhuayuan.parking.plugin.parking.che_an.request.CheAnQueryParkingFeeRequestData;
import com.sxhuayuan.parking.plugin.parking.result.McardAddResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardCancelResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardChargeOrderCreateResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardQueryChargeOptionsResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardQueryResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.ParkingLotInfoQueryResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.QueryParkingFeeResultWrap;
import com.sxhuayuan.parking.queue.msg.NotifyParkingLotMsg;
import com.sxhuayuan.parking.service.MemberCarPlateService;
import com.sxhuayuan.parking.service.MonthCardOrderService;
import com.sxhuayuan.parking.service.OrderService;
import com.sxhuayuan.parking.service.ParkChannelService;
import com.sxhuayuan.parking.service.ParkingInService;
import com.sxhuayuan.parking.service.ParkingLotService;
import com.sxhuayuan.parking.utils.DateUtils;
import com.sxhuayuan.parking.utils.SettingUtils;
import com.sxhuayuan.parking.utils.SpringUtils;

@Component(CheAnParkingPlugin.ID)
public class CheAnParkingPlugin extends ParkingPlugin {

	public static final String ID = "cheanParkingPlugin";
	public static final String RESP_STATUS = "status";
	public static final String PAYTYPE_WEIXIN = "7";
	public static final String PAYTYPE_ALIPAY = "5";

	Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	ParkingLotService lotService;
	@Autowired
	ParkChannelService exitService;
	@Autowired
	OrderService orderService;
	@Autowired
	MonthCardOrderService mcardOrderService;
	@Autowired
	MemberCarPlateService carPlateService;
	@Resource(name = "taskExecutor")
	ThreadPoolTaskExecutor executor;
	@Autowired
	ParkingInService inService;

	@Override
	public String getId() {
		return ID;
	}

	@Override
	public String getName() {
		return "车安通";
	}

	@Override
	public boolean isSupportOrderNotify() {
		return true;
	}

	@Override
	public ParkFeeCacheBean saveParkInRecord(String lotSn, String carPlate, String resp) {
		JSONObject jo = JSON.parseObject(resp).getJSONObject("data");
		ParkingLot lot = lotService.findBySn(lotSn);
		carPlate = jo.getString("carno");
		Date inTime = DateUtils.parse(jo.getString("entertime"));

		/***** 因为车安的入场记录是在用户付款的时候才去获取的，所以这里要保存一下入场记录 *****/
		ParkingIn in = inService.enter(lot, carPlate, inTime, null, lot.getFreeMinutes(), null);
		String lotOrderSn = jo.getString("orderNo");
		// Date startTime = DateUtils.parse(httpResp.getString("calcstarttime"));
		Date endTime = DateUtils.parse(jo.getString("calcendtime"));
		// 注意这里是应付金额，已减去优惠金额
		BigDecimal money = SettingUtils.get().setScale(new BigDecimal(jo.getFloatValue("parkcost")));
		// 总优惠 金额
		float shoppingDiscount = jo.getFloatValue("shoppingDiscount");
		float billDiscount = jo.getFloatValue("billDiscount");
		float scoreDiscount = jo.getFloatValue("scoreDiscount");
		BigDecimal discount = SettingUtils.get().setScale(BigDecimal.valueOf((shoppingDiscount + billDiscount + scoreDiscount)));
		// 更新到出场费用缓存中
		ParkFeeCacheBean bean = new ParkFeeCacheBean();
		bean.setCarPlate(carPlate);
		bean.setDiscountFee(discount.floatValue());
		bean.setEndTime(endTime);
		bean.setLotOrderNo(lotOrderSn);
		bean.setParkPluginId(ID);
		bean.setTotalFee(SettingUtils.get().setScale(money.add(discount)).floatValue());
		bean.setUniqueId(in.getUniqueId());
		return bean;
	}

	@Override
	public int compareTo(ParkingPlugin o) {
		return 0;
	}

	private String nonce() {
		return String.valueOf((int) (Math.random() * 100));
	}

	private String sign(Map<String, Object> map, String dataJson, String key) {
		String[] array = map.values().toArray(new String[0]);
		Arrays.sort(array);
		StringBuilder builder = new StringBuilder();
		for (String string : array) {
			builder.append(string);
		}
		if (dataJson != null)
			builder.append(dataJson);
		log.debug("密钥={}, 签名字串: {}", key, builder.toString());
		try {
			String macData = builder.toString();
			Mac mac = Mac.getInstance("HMACSHA1");
			byte[] secretByte = key.getBytes("UTF-8");
			byte[] dataBytes = macData.getBytes("UTF-8");
			SecretKey secret = new SecretKeySpec(secretByte, "HMACSHA1");
			mac.init(secret);
			byte[] doFinal = mac.doFinal(dataBytes);
			String checksum = Base64.getEncoder().encodeToString(doFinal);
			return checksum;
		} catch (Exception e) {
			throw new MyException(RespMessage.Status.ERROR, "接口调用失败:" + e.getMessage());
		}
	}

	/**
	 * 6秒超时
	 * 
	 * @param lotSn
	 * @param uri
	 * @param data
	 * @return
	 */
	private String httpPost(String lotSn, String uri, CheAnBaseData data) {

		ParkingLot lot = lotService.findBySn(lotSn);

		Map<String, Object> body = new LinkedHashMap<>();

		body.put("from", lot.getApiUser());
		body.put("timestamp", DateUtils.format());
		body.put("nonce", nonce());
		body.put("sign", sign(body, JSON.toJSONString(data), lot.getApiKey()));
		body.put("branchno", lot.getSn());
		if (data != null) {
			body.put("data", data);
		}

		String resp = postJson(lotSn, lot.getApiUrl() + uri, JSON.toJSONString(body), lot.getIsTcp());

		return resp;
	}

	/**
	 * 6秒超时
	 * 
	 * @param lotSn
	 * @param uri
	 * @param data
	 * @return
	 */
	private String httpPostMap(String lotSn, String uri, Map data) {

		ParkingLot lot = lotService.findBySn(lotSn);

		Map<String, Object> body = new LinkedHashMap<>();

		body.put("from", lot.getApiUser());
		body.put("timestamp", DateUtils.format());
		body.put("nonce", nonce());
		body.put("sign", sign(body, data == null ? null : JSON.toJSONString(data), lot.getApiKey()));
		body.put("branchno", lot.getSn());
		if (data != null) {
			body.put("data", data);
		}

		String resp = postJson(lotSn, lot.getApiUrl() + uri, JSON.toJSONString(body), lot.getIsTcp());

		return resp;
	}

	@Override
	public QueryParkingFeeResultWrap queryParkingFee(ParkingLot lot, String carPlate) {
		log.debug("调用接口查询停车费: lotSn={}, carPlate={}", lot.getSn(), carPlate);
		CheAnQueryParkingFeeRequestData data = new CheAnQueryParkingFeeRequestData();
		data.setCredential(carPlate);
		String resp = httpPost(lot.getSn(), "/api.aspx/calc", data);
		if (resp == null) {
			throw new MyException(RespMessage.Status.ERROR, Message.COMMON_SERVER_CONNECTION_FAILURE);
		}
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		QueryParkingFeeResultWrap rs = new QueryParkingFeeResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (isSuccess) {
			JSONObject respData = httpResp.getJSONObject("data");
			rs.setCardNo(respData.getString("cardNo"));
			rs.setCarPlate(carPlate);
			Float fee = respData.getFloatValue("parkcost");
			// 总计
			rs.setCalcFee(fee);
			// 实收=总计-优惠
			rs.setFee(respData.getFloatValue("amount"));
			rs.setCalcStartTime(respData.getString("calcstarttime"));
			rs.setCalcEndTime(respData.getString("calcendtime"));
			rs.setExtraMchid(lot.getSn());
			rs.setEntertime(respData.getString("entertime"));
			rs.setParktimeMinute(respData.getInteger("parktime"));
			rs.setExtraPluginId(ID);
			// 车场订单号
			rs.setLotOrderNo(respData.getString("orderNo"));
			// 车场流水号
			rs.setNo(respData.getString("chargeSeqNo"));
			rs.setRules(respData.getString("priceRule"));
			Long uniqueId = submitUpdateOriginalInfoTask(lot.getSn(), carPlate, fee, resp);
			rs.setUniqueId(uniqueId != null ? String.valueOf(uniqueId) : "");
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public QueryParkingFeeResultWrap queryLeavingCarParkingLotOrder(ParkingLot lot, String exitSn, Member member) {
		log.debug("获取车辆信息: exitSn={}", exitSn);
		long bt = System.currentTimeMillis();
		ParkChannel exit = exitService.findBySn(exitSn);
		CheAnQueryLeavingCarParkingFeeRequestData data = new CheAnQueryLeavingCarParkingFeeRequestData();
		data.setDeviceId(exit.getDeviceId());
		data.setOpenId(member.getOpenid());
		String resp = httpPost(lot.getSn(), "/api.aspx/park.out.notice", data);
		if (resp == null) {
			throw new MyException(RespMessage.Status.ERROR, Message.COMMON_SERVER_CONNECTION_FAILURE);
		}
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		QueryParkingFeeResultWrap rs = new QueryParkingFeeResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (isSuccess) {
			JSONObject respData = httpResp.getJSONObject("data");
			rs.setCardNo(respData.getString("cardNo"));
			rs.setCarPlate(respData.getString("carno"));
			// 总计
			Float fee = respData.getFloatValue("parkcost");
			rs.setCalcFee(fee);
			// 实收=总计-优惠
			rs.setFee(respData.getFloatValue("amount"));
			rs.setCalcStartTime(respData.getString("calcstarttime"));
			rs.setCalcEndTime(respData.getString("calcendtime"));
			rs.setExtraMchid(lot.getSn());
			rs.setEntertime(respData.getString("entertime"));
			rs.setParktimeMinute(respData.getInteger("parktime"));
			rs.setExtraPluginId(ID);
			// 车场订单号
			rs.setLotOrderNo(respData.getString("orderNo"));
			// 车场流水号
			rs.setNo(respData.getString("chargeSeqNo"));
			rs.setRules(respData.getString("priceRule"));
			Long uniqueId = submitUpdateOriginalInfoTask(lot.getSn(), rs.getCarPlate(), fee, resp);
			rs.setUniqueId(uniqueId != null ? String.valueOf(uniqueId) : "");
			log.debug("execute time: {}", System.currentTimeMillis() - bt);
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public boolean notifyParkingFeeOrderSuccess(NotifyParkingLotMsg notify) {
		String orderSn = notify.getLocalOrderSn();
		String lotSn = notify.getLocalLotSn();
		String carPlate = notify.getCarPlate();
		log.debug("通知车场: orderSn = {}", orderSn);
		Order order = orderService.findBySn(orderSn);
		if (order != null) {
			// if (order.getPayStatus() == PayStatus.success) {
			CheAnMcardNotifyChargeSuccessRequestData data = new CheAnMcardNotifyChargeSuccessRequestData();
			data.setCredential(order.getCarPlate());
			data.setOrderNo(order.getLotOrderNo());
			data.setParkcost(String.format("%.2f", order.getMoney()));
			data.setPayType(getCheAnPayType(order.getPlatform()));
			data.setThirdPayId(order.getSn());
			String resp = httpPost(order.getParkingLotSn(), "/api.aspx/commit", data);
			if (resp == null) {
				throw new MyException(RespMessage.Status.ERROR, Message.COMMON_SERVER_CONNECTION_FAILURE);
			}
			JSONObject httpResp = JSON.parseObject(resp);
			boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
			if (isSuccess) {
				orderService.notifySuccess(order);
			}
			return isSuccess;
			// }
			// throw new RuntimeException("订单未支付");
		}
		throw new RuntimeException(SpringUtils.getMessage(Message.ORDER_NOT_EXISTS));
	}

	@Override
	public boolean notifyMonthCardChargeOrderSuccess(String order, String lotSn, String carPlate) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public McardQueryResultWrap monthCardQuery(String lotSn, MemberCarPlate carPlate) {
		log.debug("调用接口查询月卡信息: lotSn={}, carPlate={}", lotSn, carPlate);
		CheAnMcardQueryRequestData data = new CheAnMcardQueryRequestData();
		data.setCredential(carPlate.getCarPlate());
		String resp = httpPost(lotSn, "/api.aspx/park.mcard.info", data);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		McardQueryResultWrap rs = new McardQueryResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		rs.setCarPlate(carPlate.getCarPlate());
		rs.setCarPlateId(carPlate.getId());
		if (isSuccess) {
			JSONObject respData = httpResp.getJSONObject("data");
			rs.setUserNo(respData.getString("userNo"));
			rs.setName(respData.getString("name"));
			rs.setChargeBy(respData.getString("chargeBy"));
			rs.setCurrExpiryDate(respData.getString("expirydate"));
			rs.setPreExpiryDate(respData.getString("newexpirydate"));
			rs.setMonthlyRent(respData.getString("monthlyrent"));
			// rs.setCarPlate(respData.getString("carno"));
			rs.setTariffId(respData.getString("tariffid"));
			// 车位数量
			rs.setBerth(respData.getString("berth"));
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public McardQueryResultWrap monthCardChargePreview(String lotSn, String carPlate, Integer month) {
		log.debug("调用接口查询月卡信息: lotSn={}, carPlate={}", lotSn, carPlate);
		Assert.notNull(lotSn, "lotSn is null");
		Assert.notNull(carPlate, "carPlate is null");
		Assert.notNull(month, "month is null");
		CheAnMcardQueryRequestData data = new CheAnMcardQueryRequestData();
		data.setCredential(carPlate);
		data.setNumber(String.valueOf(month));
		String resp = httpPost(lotSn, "/api.aspx/park.mcard.info", data);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		McardQueryResultWrap rs = new McardQueryResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (isSuccess) {
			JSONObject respData = httpResp.getJSONObject("data");
			rs.setUserNo(respData.getString("userNo"));
			rs.setName(respData.getString("name"));
			rs.setChargeBy(respData.getString("chargeBy"));
			rs.setCurrExpiryDate(respData.getString("expirydate"));
			rs.setPreExpiryDate(respData.getString("newexpirydate"));
			rs.setMonthlyRent(respData.getString("monthlyrent"));
			rs.setCarPlate(respData.getString("carno"));
			rs.setTariffId(respData.getString("tariffid"));
			// 车位数量
			rs.setBerth(respData.getString("berth"));
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public McardQueryChargeOptionsResultWrap monthCardQueryChargeOptions(String lotSn) {
		log.debug("调用接口查询月卡信息: lotSn={}", lotSn);
		String resp = httpPost(lotSn, "/api.aspx/park.monthtariffs.get", null);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		McardQueryChargeOptionsResultWrap rs = new McardQueryChargeOptionsResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (isSuccess) {
			JSONArray jsonArray = httpResp.getJSONArray("data");
			List<McardChargeOption> options = new ArrayList<McardChargeOption>(jsonArray.size());
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject o = jsonArray.getJSONObject(i);
				options.add(new McardChargeOption(o.getString("TariffID"), o.getString("TariffName"), o.getString("CarTypeID"), o.getInteger("Charge")));
			}
			rs.setOptions(options);
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public McardChargeOrderCreateResultWrap monthCardCreateOrder(MemberCarPlate memberCarPlate, CreateMcardChargeOrderDTO dto, Platform platform) {
		log.debug("调用接口创建月卡缴费订单: lotSn={}", dto.getLotSn());
		McardQueryResultWrap mcardQueryResultWrap = monthCardChargePreview(dto.getLotSn(), memberCarPlate.getCarPlate(), dto.getMonthNum());
		if (mcardQueryResultWrap.getIsSuccess()) {
			dto.setCurrExpireDate(mcardQueryResultWrap.getCurrExpiryDate());
			dto.setPreExpireDate(mcardQueryResultWrap.getPreExpiryDate());
			log.debug("当前过期时间: {}, 缴费后过期时间: {}", dto.getCurrExpireDate(), dto.getPreExpireDate());
		} else {
			throw new MyException(RespMessage.Status.ERROR, mcardQueryResultWrap.getMsg());
		}
		CheAnMcardChargeOrderCreateRequestData data = new CheAnMcardChargeOrderCreateRequestData();
		Map<String, McardChargeOption> monthCardChargeOptionsMap = super.getMonthCardChargeOptionsMap(dto.getLotSn());
		if (monthCardChargeOptionsMap == null || !monthCardChargeOptionsMap.containsKey(dto.getTariffId()))
			throw new MyException(RespMessage.Status.ERROR, Message.MONTH_CARD_CHARGE_OPTION_NOT_FOUND);
		McardChargeOption option = monthCardChargeOptionsMap.get(dto.getTariffId());
		BigDecimal fee = calcMonthCardOrderReceivableFee(option, dto.getMonthNum());
		BigDecimal dtoFee = SettingUtils.get().setScale(new BigDecimal(dto.getMoney()));
		if (fee.compareTo(dtoFee) != 0) {
			throw new MyException(Message.MONTH_CARD_ORDER_MONEY_NOT_MATCH);
		}
		data.setAeceivable(fee.floatValue());
		data.setAmount(fee.floatValue());
		data.setCredential(memberCarPlate.getCarPlate());
		data.setPayType(getCheAnPayType(platform));
		data.setCurrExpireDate(dto.getCurrExpireDate());
		data.setPreExpireDate(dto.getPreExpireDate());
		data.setRemark(dto.getRemark());
		String resp = httpPost(dto.getLotSn(), "/api.aspx/park.mcard.order.create", data);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		McardChargeOrderCreateResultWrap rs = new McardChargeOrderCreateResultWrap(isSuccess, null);
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (isSuccess) {
			JSONObject respData = httpResp.getJSONObject("data");
			rs.setCardNo(respData.getString("cardNo"));
			rs.setCardId(respData.getString("cardId"));
			rs.setCarPlate(memberCarPlate.getCarPlate());
			rs.setLotOrderNo(respData.getString("orderNo"));
			rs.setMonthNum(dto.getMonthNum());
			rs.setMonthlyRent(option.getCharge());
			rs.setPreExpireTime(dto.getPreExpireDate());
			rs.setLotSn(dto.getLotSn());
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public ParkingLotInfoQueryResultWrap parkingLotInfoQuery(String lotSn) {
		log.debug("调用接口查询车场信息: lotSn={}", lotSn);
		String resp = httpPost(lotSn, "/api.aspx/park.params.get", null);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		ParkingLotInfoQueryResultWrap rs = new ParkingLotInfoQueryResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (isSuccess) {
			JSONObject respData = httpResp.getJSONObject("data");
			rs.setFreeLeaveMinutes(respData.getInteger("FreeLeaveMinutes"));
			rs.setFreeMinutes(respData.getInteger("FreeMinutes"));
			rs.setHourCharged(respData.getString("HourCharged"));
		} else {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public McardCancelResultWrap monthCardCancel(String lotSn, String carPlate) {
		log.debug("调用接口注销月卡: lotSn={}, carPlate={}", lotSn, carPlate);
		CheAnMcardCancelRequestData data = new CheAnMcardCancelRequestData();
		data.setCredential(carPlate);
		String resp = httpPost(lotSn, "/api.aspx/pub.card.cancel", data);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		McardCancelResultWrap rs = new McardCancelResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (!isSuccess) {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public McardAddResultWrap monthCardAdd(String lotSn, String carPlate) {
		log.debug("调用接口添加月卡(卡发行): lotSn={}, carPlate={}", lotSn, carPlate);
		CheAnMcardAddRequestData data = new CheAnMcardAddRequestData();
		data.setNumNo(carPlate);
		data.setStartDate(DateUtils.format());
		// 10年过期
		data.setExpiryDate(DateUtils.format(DateUtils.add(DateUtils.getTime(), Calendar.YEAR, 99)));
		String resp = httpPost(lotSn, "/api.aspx/pub.card.add", data);
		JSONObject httpResp = JSON.parseObject(resp);
		boolean isSuccess = httpResp.getBooleanValue(RESP_STATUS);
		McardAddResultWrap rs = new McardAddResultWrap();
		rs.setTime(DateUtils.parse(httpResp.getString("time")));
		rs.setIsSuccess(isSuccess);
		if (!isSuccess) {
			rs.setMsg(httpResp.getString("message"));
		}
		return rs;
	}

	@Override
	public String execute(String api, String lotSn, Map map) {
		return httpPostMap(lotSn, api, map);
	}

	@Override
	public void afterInNoticeHanler(HttpServletRequest request, HttpServletResponse response, ParkingLot parkingLot) {

	}

	@Override
	public void afterOutNoticeHanler(HttpServletRequest request, HttpServletResponse response, ParkingLot parkingLot) {

	}
	
	@Override
	public void beforeOutNoticeHandler(HttpServletRequest request, HttpServletResponse response, ParkingLot parkingLot) {
		// TODO Auto-generated method stub
		
	}

	private String getCheAnPayType(Platform platform) {
		switch (platform) {
		case weixin:
			return PAYTYPE_WEIXIN;
		case alipay:
			return PAYTYPE_ALIPAY;
		default:
			return "";
		}
	}
}